import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FlatButton(
              onPressed: () => {
                Navigator.push(context,
                    new MaterialPageRoute(builder: (context) {
                  return TapboxA(key);
                }))
              },
              child: Text("Widget管理自身状态"),
              textColor: Colors.blue,
            ),
            FlatButton(
              onPressed: () => {
                Navigator.push(context,
                    new MaterialPageRoute(builder: (context) {
                  return ParentWidget();
                }))
              },
              child: Text("父Widget管理子Widget的状态"),
              textColor: Colors.blue,
            ),
            FlatButton(
              onPressed: () => {
                Navigator.push(context,
                    new MaterialPageRoute(builder: (context) {
                      return ParentWidgetC();
                    }))
              },
              child: Text("混合状态管理"),
              textColor: Colors.blue,
            ),
          ],
        ),
      ),
    );
  }
}

// -------------------------- Widget管理自身状态
//管理TapboxA的状态。
//定义_active：确定盒子的当前颜色的布尔值。
//定义_handleTap()函数，该函数在点击该盒子时更新_active，并调用setState()更新UI。
//实现widget的所有交互式行为。

class TapboxA extends StatefulWidget {
  TapboxA(Key key) : super(key: key);

  @override
  _TapboxAState createState() => new _TapboxAState();
}

class _TapboxAState extends State<TapboxA> {
  bool _active = false;

  void _handleTap() {
    setState(() {
      _active = !_active;
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
          child: Center(
            child: Text(_active ? "Active" : "Inactive",
                style: TextStyle(fontSize: 32, color: Colors.blue)),
          ),
          width: 200,
          height: 200,
          decoration: BoxDecoration(
            color: _active ? Colors.lightGreen[700] : Colors.grey[600],
          )),
    );
  }
}

// --------------------------- 父Widget管理子Widget的状态
// 为TapboxB 管理_active状态。
// 实现_handleTapboxChanged()，当盒子被点击时调用的方法。
// 当状态改变时，调用setState()更新UI。

// 继承StatelessWidget类，因为所有状态都由其父组件处理。
// 当检测到点击时，它会通知父组件。
class ParentWidget extends StatefulWidget {
  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
      child: new TapboxB(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }
}

class TapboxB extends StatelessWidget {
  final bool active;
  final ValueChanged<bool> onChanged;

  TapboxB({Key key, this.active: false, @required this.onChanged})
      : super(key: key);

  void _handleTap() {
    onChanged(!active);
  }

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Center(
          child: Text(
            active ? "Active" : "Inactive",
            style: TextStyle(fontSize: 32, color: Colors.white),
          ),
        ),
        width: 200,
        height: 200,
        decoration: BoxDecoration(
            color: active ? Colors.lightGreen[700] : Colors.grey[600]),
      ),
    );
  }
}

// -------------------------- 混合状态管理

//管理_active 状态。
//实现 _handleTapboxChanged() ，当盒子被点击时调用。
//当点击盒子并且_active状态改变时调用setState()更新UI

//管理_highlight 状态。
//GestureDetector监听所有tap事件。当用户点下时，它添加高亮（深绿色边框）；当用户释放时，会移除高亮。
//当按下、抬起、或者取消点击时更新_highlight状态，调用setState()更新UI。
//当点击时，将状态的改变传递给父组件

class ParentWidgetC extends StatefulWidget {
  @override
  _ParentWidgetCState createState() {
    return _ParentWidgetCState();
  }
}

class _ParentWidgetCState extends State<ParentWidgetC> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: TapboxC(active: _active, onChanged: _handleTapboxChanged),
    );
  }
}

class TapboxC extends StatefulWidget {
  final bool active;
  final ValueChanged<bool> onChanged;

  TapboxC({Key key, this.active, @required this.onChanged}) : super(key: key);

  @override
  _TapboxCState createState() => _TapboxCState();
}

class _TapboxCState extends State<TapboxC> {
  bool _highlight = false;

  void _handleTapDown(TapDownDetails details) {
    setState(() {
      _highlight = true;
    });
  }

  void _handleTapUp(TapUpDetails details) {
    setState(() {
      _highlight = false;
    });
  }

  void _handleTap() {
    widget.onChanged(!widget.active);
  }

  void _handleTapCancel() {
    setState(() {
      _highlight = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      onTapDown: _handleTapDown,
      onTapUp: _handleTapUp,
      onTapCancel: _handleTapCancel,
      child: Container(
        child: Center(
          child: Text(widget.active ? 'Active' : 'Inactive',
              style: new TextStyle(fontSize: 32.0, color: Colors.white)),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: widget.active ? Colors.lightGreen[700] : Colors.grey[600],
          border: _highlight
              ? Border.all(color: Colors.teal[700], width: 10.0)
              : null,
        ),
      ),
    );
  }
}
